package com.cloudweb.oa.controller;

import cn.js.fan.cache.jcs.RMCache;
import cn.js.fan.db.ResultIterator;
import cn.js.fan.db.ResultRecord;
import cn.js.fan.db.SQLFilter;
import cn.js.fan.util.*;
import cn.js.fan.web.Global;
import com.alibaba.fastjson.JSONObject;
import com.cloudweb.oa.exception.ValidateException;
import com.cloudweb.oa.utils.ResponseUtil;
import com.cloudweb.oa.utils.SysUtil;
import com.cloudweb.oa.vo.Result;
import com.cloudwebsoft.framework.db.JdbcTemplate;
import com.cloudwebsoft.framework.util.LogUtil;
import com.redmoon.oa.Config;
import com.redmoon.oa.SpConfig;
import com.redmoon.oa.kernel.License;
import com.redmoon.oa.person.PlanDb;
import com.redmoon.oa.ui.SkinMgr;
import com.redmoon.oa.util.TwoDimensionCode;
import io.swagger.annotations.*;
import org.apache.commons.jcs3.access.exception.CacheException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.sql.SQLException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

@Controller
@RequestMapping("/admin")
public class SysController {

    @Autowired
    HttpServletRequest request;

    @Autowired
    ResponseUtil responseUtil;

    @ApiOperation(value = "停用缓存", notes = "停用缓存", httpMethod = "POST")
    @ApiResponses({@ApiResponse(code = 200, message = "操作成功")})
    @PreAuthorize("hasAnyAuthority('admin')")
    @RequestMapping(value = "/stopCache", produces = {"text/html;charset=UTF-8;", "application/json;"})
    @ResponseBody
    public Result<Object> stopCache() throws ValidateException {
        RMCache rmcache = RMCache.getInstance();
        rmcache.setCanCache(false);
        return new Result<>();
    }

    @ApiOperation(value = "启用缓存", notes = "启用缓存", httpMethod = "POST")
    @ApiResponses({@ApiResponse(code = 200, message = "操作成功")})
    @PreAuthorize("hasAnyAuthority('admin')")
    @RequestMapping(value = "/startCache", produces = {"text/html;charset=UTF-8;", "application/json;"})
    @ResponseBody
    public Result<Object> startCache() throws ValidateException {
        RMCache rmcache = RMCache.getInstance();
        rmcache.setCanCache(true);
        return new Result<>();
    }

    @ApiOperation(value = "清除缓存", notes = "清除缓存", httpMethod = "POST")
    @ApiResponses({@ApiResponse(code = 200, message = "操作成功")})
    @PreAuthorize("hasAnyAuthority('admin')")
    @RequestMapping(value = "/clearCache", produces = {"text/html;charset=UTF-8;", "application/json;"})
    @ResponseBody
    public Result<Object> clearCache() throws ValidateException {
        RMCache rmcache = RMCache.getInstance();
        try {
            rmcache.clear();
        } catch (CacheException e) {
            LogUtil.getLog(getClass()).error(e);
        }
        return new Result<>();
    }

    @ApiOperation(value = "垃圾收集", notes = "垃圾收集", httpMethod = "POST")
    @ApiResponses({@ApiResponse(code = 200, message = "操作成功")})
    @PreAuthorize("hasAnyAuthority('admin')")
    @RequestMapping(value = "/gc", produces = {"text/html;charset=UTF-8;", "application/json;"})
    @ResponseBody
    public Result<Object> gc() throws ValidateException {
        Runtime runtime = Runtime.getRuntime();
        runtime.gc();
        return new Result<>();
    }

    @ApiOperation(value = "系统变量页面", notes = "系统变量页面", httpMethod = "POST")
    @ApiResponses({@ApiResponse(code = 200, message = "操作成功")})
    @PreAuthorize("hasAnyAuthority('admin')")
    @RequestMapping(value = "/configSysPage")
    @ResponseBody
    public Result<Object> configSysPage() throws ValidateException {
        JSONObject json = (JSONObject) JSONObject.toJSON(Global.getInstance());
        json.put("realPath", Global.getRealPath());
        return new Result<>(json);
    }

    @ApiOperation(value = "保存系统变量", notes = "保存系统变量", httpMethod = "POST")
    @ApiResponses({@ApiResponse(code = 200, message = "操作成功")})
    @PreAuthorize("hasAnyAuthority('admin')")
    @RequestMapping(value = "/updateConfigSys", produces = {"text/html;charset=UTF-8;", "application/json;"})
    @ResponseBody
    public Result<Object> updateConfigSys() throws ValidateException {
        XMLConfig cfg = new XMLConfig("config_sys.xml", false, "utf-8");
        Enumeration e = request.getParameterNames();
        while (e.hasMoreElements()) {
            String fieldName = (String) e.nextElement();
            if (fieldName.startsWith("Application")) {
                String value = ParamUtil.get(request, fieldName);
                cfg.set(fieldName, value);
            }
        }
        cfg.writemodify();
        Global.getInstance().init();
        TwoDimensionCode.generate2DCodeByMobileClient();//生成手机端二维码
        return new Result<>();
    }

    @ApiOperation(value = "许可证页面", notes = "许可证页面", httpMethod = "POST")
    @ApiResponses({@ApiResponse(code = 200, message = "操作成功")})
    @PreAuthorize("hasAnyAuthority('admin')")
    @RequestMapping(value = "/licensePage")
    @ResponseBody
    public Result<Object> licensePage() {
        JSONObject json = (JSONObject) JSONObject.toJSON(License.getInstance());

        Config oaCfg = Config.getInstance();
        SpConfig spCfg = new SpConfig();
        String version = StrUtil.getNullStr(oaCfg.get("version"));
        String spVersion = StrUtil.getNullStr(spCfg.get("version"));

        json.put("version", version);
        json.put("spVersion", spVersion);
        json.put("versionType", License.getInstance().getVersionType().equals(License.VERSION_TYPE_PREMIUM) ? "卓越版":"优享版");
        return new Result<>(json);
    }

    @PreAuthorize("hasAnyAuthority('admin')")
    @RequestMapping(value = "/license")
    @ResponseBody
    public String license(Model model) throws ValidateException {
        model.addAttribute("skinPath", SkinMgr.getSkinPath(request, false));

        model.addAttribute("license", License.getInstance());

        Config oaCfg = Config.getInstance();
        SpConfig spCfg = new SpConfig();
        String version = StrUtil.getNullStr(oaCfg.get("version"));
        String spVersion = StrUtil.getNullStr(spCfg.get("version"));

        model.addAttribute("version", version);
        model.addAttribute("spVersion", spVersion);

        return "th/admin/license";
    }

    @ApiOperation(value = "系统环境", notes = "系统环境", httpMethod = "POST")
    @ApiResponses({@ApiResponse(code = 200, message = "操作成功")})
    @PreAuthorize("hasAnyAuthority('admin')")
    @RequestMapping(value = "/env")
    @ResponseBody
    public Result<Object> env() throws ValidateException {
        JSONObject json = new JSONObject();

        RMCache rmcache = RMCache.getInstance();
        Runtime runtime = Runtime.getRuntime();

        double freeMemory = (double) runtime.freeMemory() / (1024 * 1024);
        double totalMemory = (double) runtime.totalMemory() / (1024 * 1024);
        double maxMemory = Runtime.getRuntime().maxMemory() / (1024 * 1024);
        double usedMemory = totalMemory - freeMemory;
        double percentFree = (freeMemory / totalMemory) * 100.0;
        int free = 100 - (int) Math.round(percentFree);

        DecimalFormat mbFormat = new DecimalFormat("#0.00");
        DecimalFormat percentFormat = new DecimalFormat("#0.0");

        json.put("percentFree", percentFormat.format(percentFree));
        json.put("usedMemory", percentFormat.format(usedMemory));

        json.put("totalMemory", mbFormat.format(totalMemory));
        json.put("maxMemory", mbFormat.format(maxMemory));

        json.put("maxWebeditFileSize", NumberUtil.round((double) Global.getInstance().getMaxSize() / 1024000, 1));
        json.put("fileSize", NumberUtil.round((double) Global.FileSize / 1000, 1));

        json.put("numBlocks", 50);
        json.put("canCache", rmcache.getCanCache());

        json.put("processors", runtime.availableProcessors());

        List<Integer> list = new ArrayList<>();
        int numBlocks = 50;
        int blockSize = 100 / numBlocks;

        for (int i = 0; i < numBlocks; i++) {
            if ((i * (100 / numBlocks)) < free) {
                list.add(0);
            } else {
                list.add(1);
            }
        }

        json.put("blockWidth", blockSize);
        json.put("blockList", list);

        return new Result<>(json);
    }

    @ApiOperation(value = "清空系统", notes = "保存系统变量", httpMethod = "POST")
    @ApiResponses({@ApiResponse(code = 200, message = "操作成功")})
    @PreAuthorize("hasAnyAuthority('admin')")
    @RequestMapping(value = "/clearSys", produces = {"text/html;charset=UTF-8;", "application/json;"})
    @ResponseBody
    public Result<Object> clearSys(@RequestParam(defaultValue = "false") Boolean isClearUser) {
        try {
            com.redmoon.oa.sys.SysUtil.initSystem(isClearUser);
        } catch (ErrMsgException e) {
            return new Result<>(e.getMessage());
        }
        return new Result<>();
    }

    @ApiOperation(value = "回收资源", notes = "回收资源", httpMethod = "POST")
    @ApiResponses({@ApiResponse(code = 200, message = "操作成功")})
    @PreAuthorize("hasAnyAuthority('admin')")
    @RequestMapping(value = "/reclaim", produces = {"text/html;charset=UTF-8;", "application/json;"})
    @ResponseBody
    public Result<Object> reclaim() {
        String[] modules = ParamUtil.getParameters(request, "module");
        if (modules == null) {
            return new Result<>(false, "请选择模块");
        }
        String userStrs = ParamUtil.get(request, "users");
        String[] users = StrUtil.split(userStrs, ",");
        if (users == null) {
            return new Result<>(false, "请选择用户");
        }

        String beginDate = ParamUtil.get(request, "beginDate");
        if ("".equals(beginDate)) {
            return new Result<>(false, "请填写开始日期");
        }
        String endDate = ParamUtil.get(request, "endDate");
        String sql = "";
        try {
            for (String userName : users) {
                for (String module : modules) {
                    if ("plan".equals(module)) {
                        sql = "select id from user_plan where userName=" + StrUtil.sqlstr(userName);
                        if ("".equals(endDate)) {
                            sql += " and myDate<=" + SQLFilter.getDateStr(beginDate, "yyyy-MM-dd");
                        } else {
                            sql += " and myDate>=" + SQLFilter.getDateStr(beginDate, "yyyy-MM-dd") + " and myDate<=" + SQLFilter.getDateStr(endDate, "yyyy-MM-dd");
                        }
                        JdbcTemplate jt = new JdbcTemplate();
                        ResultIterator ri = null;
                        ri = jt.executeQuery(sql);

                        PlanDb pd = new PlanDb();
                        while (ri.hasNext()) {
                            ResultRecord rr = ri.next();
                            int id = rr.getInt(1);
                            pd = pd.getPlanDb(id);
                            pd.del();
                        }
                    } else if ("message".equals(module)) {
                        sql = "select id from oa_message where receiver=" + StrUtil.sqlstr(userName);
                        if (endDate.equals("")) {
                            sql += " and send_time<=" + SQLFilter.getDateStr(beginDate, "yyyy-MM-dd");
                        } else {
                            sql += " and send_time>=" + SQLFilter.getDateStr(beginDate, "yyyy-MM-dd") + " and send_time<=" + SQLFilter.getDateStr(endDate, "yyyy-MM-dd");
                        }
                        JdbcTemplate jt = new JdbcTemplate();
                        ResultIterator ri = jt.executeQuery(sql);
                        com.redmoon.oa.message.MessageDb md = new com.redmoon.oa.message.MessageDb();
                        while (ri.hasNext()) {
                            ResultRecord rr = (ResultRecord) ri.next();
                            int id = rr.getInt(1);
                            md = (com.redmoon.oa.message.MessageDb) md.getMessageDb(id);
                            md.del();
                        }
                    } else if ("address".equals(module)) {
                        sql = "select id from address where username=" + StrUtil.sqlstr(userName);
                        if (endDate.equals("")) {
                            sql += " and adddate<=" + SQLFilter.getDateStr(beginDate, "yyyy-MM-dd");
                        } else {
                            sql += " and adddate>=" + SQLFilter.getDateStr(beginDate, "yyyy-MM-dd") + " and adddate<=" + SQLFilter.getDateStr(endDate, "yyyy-MM-dd");
                        }
                        JdbcTemplate jt = new JdbcTemplate();
                        ResultIterator ri = jt.executeQuery(sql);
                        com.redmoon.oa.address.AddressDb addr = new com.redmoon.oa.address.AddressDb();
                        while (ri.hasNext()) {
                            ResultRecord rr = (ResultRecord) ri.next();
                            int id = rr.getInt(1);
                            addr = addr.getAddressDb(id);
                            addr.del();
                        }
                    }
                }
            }
        } catch (SQLException e) {
            LogUtil.getLog(getClass()).error(e);
            return new Result<>(false, e.getMessage());
        }
        return new Result<>();
    }
}
